package es.guiguegon.elyeproj.loaderviewlibrary;

/*
 * Copyright 2016 Elye Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.Canvas;
import ohos.agp.render.LinearShader;
import ohos.agp.render.Paint;
import ohos.agp.render.Shader;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

class LoaderController implements AnimatorValue.ValueUpdateListener {

    private LoaderView loaderView;
    private Paint rectPaint;
    private LinearShader linearGradient;
    private float progress;
    private LoaderViewValueAnimator valueAnimator;
    private float widthWeight = LoaderConstant.MAX_WEIGHT;
    private float heightWeight = LoaderConstant.MAX_WEIGHT;
    private int width;
    private int height;
    private boolean useGradient = LoaderConstant.USE_GRADIENT_DEFAULT;
    private int corners = LoaderConstant.CORNER_DEFAULT;
    private final static int ANIMATION_CYCLE_DURATION = 2000; //milis

    public LoaderController(LoaderView view,Context mContext) {
        loaderView = view;
        init();
    }

    private void init() {
        rectPaint = new Paint();
        rectPaint.setAntiAlias(true);
        rectPaint.setFilterBitmap(true);
        loaderView.setRectColor(rectPaint);
        setValueAnimator(0.1f, 1, Animator.INFINITE);
    }

    public void onDraw(Canvas canvas) {
        onDraw(canvas, 0, 0, 0, 0);
    }

    public void onDraw(Canvas canvas, float leftPad, float topPad, float rightPad, float bottomPad) {
        float marginHeight = height * (1 - heightWeight) / 2;
        rectPaint.setAlpha(progress);
        if (useGradient) {
            prepareGradient(width * widthWeight);
        }
        canvas.drawRoundRect(new RectFloat(0 + leftPad,
                        marginHeight + topPad,
                        width * widthWeight - rightPad,
                        height - marginHeight - bottomPad),
                corners, corners,
                rectPaint);
    }

    public void onSizeChanged() {
        linearGradient = null;
        startLoading();
    }

    private void prepareGradient(float width) {
        if (linearGradient == null) {
            Point[] points = new Point[]{new Point(0,0),new Point(width,0)};
            Color[] colors = new Color[]{rectPaint.getColor(),LoaderConstant.COLOR_DEFAULT_GRADIENT};
            linearGradient = new LinearShader(points,null,colors,
                Shader.TileMode.MIRROR_TILEMODE);
        }
        rectPaint.setShader(linearGradient, Paint.ShaderType.LINEAR_SHADER);
    }

    public void startLoading() {
        if (valueAnimator != null && !loaderView.valueSet()) {
            valueAnimator.stop();
            init();
            valueAnimator.start();
        }
    }

    public void setHeightWeight(float heightWeight) {
        this.heightWeight = validateWeight(heightWeight);
    }

    public void setWidthWeight(float widthWeight) {
        this.widthWeight = validateWeight(widthWeight);
    }

    public void setUseGradient(boolean useGradient) {
        this.useGradient = useGradient;
    }

    public void setCorners(int corners) {
        this.corners = corners;
    }

    private float validateWeight(float weight) {
        if (weight > LoaderConstant.MAX_WEIGHT) {
            return LoaderConstant.MAX_WEIGHT;
        } else if(weight < LoaderConstant.MIN_WEIGHT) {
            return LoaderConstant.MIN_WEIGHT;
        } else {
            return weight;
        }
    }

    public void stopLoading() {
        if (valueAnimator != null) {
            valueAnimator.cancel();
            setValueAnimator(progress, 0, 0);
            valueAnimator.start();
        }
    }

    private void setValueAnimator(float begin, float end, int repeatCount) {
        valueAnimator = LoaderViewValueAnimator.ofFloat(begin, end);
        valueAnimator.setLoopedCount(repeatCount);
        valueAnimator.setDuration(ANIMATION_CYCLE_DURATION);
        valueAnimator.setCurveType(Animator.CurveType.LINEAR);
        valueAnimator.setValueUpdateListener(this);
    }

    public void removeAnimatorUpdateListener() {
        if (valueAnimator != null) {
            valueAnimator.cancel();
        }
        progress = 0f;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    @Override
    public void onUpdate(AnimatorValue animatorValue, float v) {
        progress = v;
        loaderView.invalidate();
    }
}
